package StratelegoGame;
import java.awt.Color;
import java.awt.event.MouseEvent;
import java.io.IOException;
import java.util.Vector;
import javax.swing.JOptionPane;
import SwingLib.Message;

/**
 * This class controls the logic behind the game. It is sort of
 * flakey and has some issues. Singleton class. Use getInstance to 
 * get the class object.
 * @author Jace Ferguson
 * @filename GameBoard2DLogic.java
 *
 */
public class GameBoard2DLogic implements GameBoardLogic {
	public static final int PLAYER_PIECE_POSITIONING = 0;
	public static final int PLAYER_ACTIVE_TURN = 1;
	public static final int PLAYER_WAITING = 2;
	public static final int PLAYER_GAME_ENDED = 3;

	/** 
	 * Get instance method.
	 */
	private static GameBoard2DLogic obj;
	public static GameBoard2DLogic getInstance()
	{
		if(GameBoard2DLogic.obj == null)
		{
			GameBoard2DLogic.obj = new GameBoard2DLogic();
		}
		return GameBoard2DLogic.obj;
	}
	private GameBoard2D board;
	private GameBoard2DPieceHoard hoard;
	private Vector<GameBoard2DPiece> pieces; 
	private int gameStatus;
	private ClientProtocol client;
	private boolean playersConnected;

	/**
	 * Construct the game board and create a vector to hold pieces.
	 */
	private GameBoard2DLogic()
	{
		this.pieces = new Vector<GameBoard2DPiece>();
		this.playersConnected = false;
		//no game is active.
		this.setStatus(GameBoard2DLogic.PLAYER_GAME_ENDED);
	}

	/**
	 * Create a piece with a given value and add it to a give space.
	 * @param pieceValue	Integer
	 * @param spaceId	Integer
	 */
	public void addOpponentPieceToSpace(Integer pieceValue, Integer spaceId)
	{
		try{
			GameBoard2DPiece piece = GameBoard2DPieceFactory.createPieceWithValue(pieceValue, null, Color.RED, GameBoard2DPiece.FOE);
			if(piece != null)
			{
				//Hide the value of the piece
				piece.getLabel().setText("");
				//Add the piece to the vector
				this.pieces.add(piece);
				GameBoard2DSpace space = this.board.getSpace(spaceId);
				if(space != null)
				{
					//Unlock the space
					space.setSpaceSetable(true);
					//Add the piece
					space.addPieceToSpace(piece);
					//Relock the space
					space.setSpaceSetable(false);
				}
				else
					new Message("Unable to add a piece to the space with id: " + spaceId + ". This game may be corrupt.");
			}
			else
				new Message("Unable to create a piece with the value of: " + pieceValue + ". This game may be corrupt.");

		}
		catch(IOException e)
		{
			new Message("Unable to construct an opponent piece.", "Piece Error", Message.ERROR);
			System.exit(-21);
		}
	}

	/**
	 * Add a game board piece to the space.
	 */
	public void addPieceToSpace(GameBoardPiece piece, GameBoardSpace space)
	{
		space.addPieceToSpace(piece);
	}

	/**
	 * Check the pieces that are on the board to see if 
	 * a winner happened because of an attack.
	 */
	public void checkForWinner()
	{
		//Start of by saying both are winners.
		boolean friend = true;
		boolean foe = true;
		GameBoard2DSpace space;
		for(GameBoard2DPiece piece : this.pieces) //Go through all the pieces.
		{
			space = piece.getSpace();
			if(piece.getType() == GameBoard2DPiece.FRIEND && friend )
			{
				//Check to see if the piece has the value of a moveable piece and that the piece is still on the board.
				if(piece.getValue() > 1 && piece.getValue() < 12 && space != null)
				{
					//Game play can still occur.
					friend = false;
				}

			}
			else if(foe) // The piece is a foe.
			{
				if(piece.getValue() > 1 && piece.getValue() < 12 && space != null)
				{
					//the foe can sill play both are play
					foe = false;
				}
			}
			else
				break; //Moveable pieces have been found on both sides. No need to look for more.
		}
		//If both are true the players tied.
		if(friend && foe)
		{
			this.drawGame();
		}
		else if(friend) //The local player wins.
		{
			this.playerWins();
		}
		else if(foe) //The opponent wins.
		{
			this.opponentWins();
		}
	}

	/**
	 * Clear the game board of all pieces
	 */
	public void clearBoard()
	{
		this.board.clearBoard();
	}

	/**
	 * Clear drag and drop capability for all pieces.
	 */
	private void clearDNDCapability()
	{
		for(GameBoard2DPiece piece : this.pieces)
		{
			piece.setTransferHandler(null);
		}
	}

	/**
	 * Clear the hoard of all pieces.
	 */
	public void clearHoard()
	{
		this.hoard.clearHoard();
	}

	/**
	 * Game play has started set the status to waiting
	 */
	public void commencePlay()
	{
		this.setStatus(GameBoard2DLogic.PLAYER_WAITING);
	}

	/** 
	 * Determine the outcome of a battle between to pieces
	 * @param src	GameBoardSpace
	 * @param tar	GameBoardSpace
	 */
	public void determineSpaceWinner(GameBoardSpace src, GameBoardSpace tar)
	{
		String opponentMessage = "";
		//Get the pieces
		GameBoard2DPiece attackerPiece = ((GameBoard2DSpace)src).getPiece();
		GameBoard2DPiece attackedPiece = ((GameBoard2DSpace)tar).getPiece();
		//Attacked piece actually wasn't there.
		if(attackedPiece == null)
		{
			this.movePieceFromSpaceToSpace(src, tar);
		}
		else if(attackerPiece == null){} // do nothing to the attacked piece.
		else if(attackedPiece.getValue() == 12) 
			//Someone captured the opponents flag.
		{
			this.removePieceFromSpace(tar);	//Remove the flag from local game
			this.client.sendRemovePieceFromSpace(this.translateSpaceId(tar.getId())); //Remove the flag from opponent game
			this.movePieceFromSpaceToSpace(src, tar); //Move the victorious piece to the flag.
			this.endTurn();
			this.playerWins(); //Game is over, local player wins.
		}
		else if(attackedPiece.getValue() == 1 && attackerPiece.getValue() != 3) 
			// Attacked piece is a bomb and the attacked isn't a miner
		{
			//Show message about attack.
			new Message("Your " + attackerPiece.getName() + " was blown up by a bomb!", "Watch out for bombs", Message.INFO);
			//Set the opponent message
			opponentMessage = "Your bomb blew up a " + attackerPiece.getName() + "! Well Played!";
			//Remove the attacker piece because he was destroyed.
			this.removePieceFromSpace(src);
			//Send remove command to opponent
			this.client.sendRemovePieceFromSpace(this.translateSpaceId(src.getId()));
		}
		else if(attackerPiece.getValue() == 11 && attackedPiece.getValue() != 10)
			//Spy attacks a player other than a marshal
		{
			//Show message about attack.
			new Message("Your " + attackerPiece.getName() + " tried to attack a " + attackedPiece.getName() + ". Train him better next time.", "Lousy Spy", Message.INFO);
			//Set the opponent message
			opponentMessage = "Your opponent lost his spy to your " + attackedPiece.getName() + ".";
			//Remove the spy piece because he can't attack anything but the marshal
			this.removePieceFromSpace(src);
			//Send remove command to opponent
			this.client.sendRemovePieceFromSpace(this.translateSpaceId(src.getId()));
		}
		else if(attackedPiece.getValue() == 11)
			//Spy gets attacked and dies no matter what.
		{
			//Show message about attack
			new Message("Your spy got attacked by a " + attackerPiece.getName(), "Bye-Bye Spy", Message.INFO);
			//Set opponent message
			opponentMessage = "Your opponent lost his spy to your " + attackedPiece.getName() + ".";
			//Remove the local spy
			this.removePieceFromSpace(tar);
			//Send remove command to client
			this.client.sendRemovePieceFromSpace(this.translateSpaceId(tar.getId()));
			//Move the attack to the spy's space
			this.movePieceFromSpaceToSpace(src, tar);
		}
		else if(attackedPiece.getValue() == attackerPiece.getValue())
			//Same value of both pieces was the same, both pieces are removed
		{
			//Show message about the attack
			new Message("Your " + attackerPiece.getName() + " attacked an equal adversary. You both died.", "Equal Treatment", Message.INFO);
			//Set opponent message
			opponentMessage = "Your " + attackedPiece.getName() + " was attacked by an equal adversary. You both died.";
			//Remove the both pieces from local game
			this.removePieceFromSpace(tar);
			this.removePieceFromSpace(src);
			//remove both pieces from opponent game
			this.client.sendRemovePieceFromSpace(this.translateSpaceId(src.getId()));
			this.client.sendRemovePieceFromSpace(this.translateSpaceId(tar.getId()));
		}
		else if(attackedPiece.getValue() > attackerPiece.getValue())
			//The attacked piece is stronger and kills attacker.
		{
			//Show message about the attack
			new Message("Your " + attackerPiece.getName() + " tried to attack a " + attackedPiece.getName() + ". Your man was no match.", "Good bye " + attackerPiece.getName(), Message.INFO);
			//Set opponent message
			opponentMessage = "Your " + attackedPiece.getName() + " won a battle with a " + attackerPiece.getName() + ".";
			//Remove the attacker from local game
			this.removePieceFromSpace(src);
			//Remove the attacker from opponent game.
			this.client.sendRemovePieceFromSpace(this.translateSpaceId(src.getId()));
		}
		else
			//The attacked piece is weaker and is killed
		{
			//Show message about the attack
			new Message("Your " + attackerPiece.getName() + " won a battle with a " + attackedPiece.getName() + ".", "Victory!", Message.INFO);
			//Set the opponent message
			opponentMessage = "Your opponent destroyed your " + attackedPiece.getName() + " with a "+attackerPiece.getName()+".";
			//Remove the attacked piece from local game.
			this.removePieceFromSpace(tar);
			//Remove the attacked piece from opponent game
			this.client.sendRemovePieceFromSpace(this.translateSpaceId(tar.getId()));
			//Move the attacker to the attacked space
			this.movePieceFromSpaceToSpace(src, tar);
		}
		if(opponentMessage.length() != 0)
			//Check to see if a message to the opponent was set.
		{
			if(this.client != null)
			{
				//Send the message to the opponent
				this.client.sendAttackMessage(opponentMessage);
			}
		}
		//Check to see if the action ended the game.
		this.checkForWinner();
		if(this.getStatus() != GameBoard2DLogic.PLAYER_GAME_ENDED)
		{
			this.endTurn();
		}
	}

	/**
	 * Display attack message from opponent
	 * @param message	String
	 */
	public void displayAttackMessage(String message)
	{
		new Message(message, "Your Opponent Attacked You", Message.INFO);
	}

	/**
	 * Display the end game message from opponent
	 * @param message	String
	 */
	public void displayResultMessage(String message)
	{
		new Message(message, "This Game Is Over", Message.INFO);
	}

	/**
	 * The game tied end the game and send a message to opponent
	 */
	public void drawGame()
	{
		this.gameOver();
		this.displayResultMessage("Miraculously you both have been defeated.");
		if(client != null)
		{
			this.client.sendResultMessage("Miraculously you both have been defeated.");
		}
	}
	/**
	 * End the game based on a client request.
	 */
	public void endGame()
	{
		this.setStatus(GameBoard2DLogic.PLAYER_GAME_ENDED);
		this.board.setAllSpacesSetablility(false);
		this.markAllPieceSelectable(false);
		//this.requestAnotherGame();
	}

	/**
	 * End a turn
	 */
	public void endTurn()
	{
		//Lock all the pieces from being selected.
		this.markAllPieceSelectable(false);
		this.setStatus(GameBoard2DLogic.PLAYER_WAITING);
		if(client != null)	//Send message to switch turns to client
			this.client.sendEndTurn();
	}

	/**
	 * End the game locally.
	 */
	public void gameOver()
	{
		this.setStatus(GameBoard2DLogic.PLAYER_GAME_ENDED);
		//Lock all the spaces
		this.board.setAllSpacesSetablility(false);
		this.markAllPieceSelectable(false);
		if(this.client != null)
			this.client.sendEndGame();
		//this.requestAnotherGame();
	}
	
	/**
	 * See if the player wants to play again.
	 */
	public void requestAnotherGame()
	{
		int newGame = JOptionPane.showConfirmDialog(null, "Play again?");
		if(newGame == 0)
		{
			this.restartGame();
		}
	}

	/**
	 * Get the game board.
	 * @return	GameBoard2D
	 */
	public GameBoard2D getBoard()
	{
		return this.board;
	}

	/**
	 * Get the client protocol from logic.
	 * @return	ClientProtocol
	 */
	public ClientProtocol getClientProtocol()
	{
		return this.client;
	}

	/**
	 * Get the game piece hoard.
	 * @return	GameBoard2DPieceHoard
	 */
	public GameBoard2DPieceHoard getHoard()
	{
		return this.hoard;
	}

	/**
	 * Check to see if two players are connected to the server.
	 * @return boolean
	 */
	public boolean getPlayersConnected()
	{
		return this.playersConnected;
	}

	/**
	 * Get the game play status.
	 * @return	Integer
	 */
	public Integer getStatus()
	{
		return this.gameStatus;
	}

	/**
	 * Initialize the piece hoard with pieces for a game.
	 * @throws IOException
	 */
	public void initializePieceHoard() throws IOException
	{
		//Clear any current pieces
		this.pieces.clear();
		//Clear pieces from the hoard
		this.hoard.clearHoard(); 
		GameBoard2DPiece piece;
		Color color = Color.BLUE;
		//Create and add pieces to the hoard.
		this.pieces.add(piece = GameBoard2DPieceFactory.createSpyPiece(null, color, GameBoard2DPiece.FRIEND));
		this.hoard.addPiece(piece);
		this.pieces.add(piece = GameBoard2DPieceFactory.createFlagPiece("images/flag.png", color, GameBoard2DPiece.FRIEND));
		this.hoard.addPiece(piece);
		this.pieces.add(piece = GameBoard2DPieceFactory.createMarshalPiece(null, color, GameBoard2DPiece.FRIEND));
		this.hoard.addPiece(piece);
		this.pieces.add(piece = GameBoard2DPieceFactory.createGeneralPiece(null, color, GameBoard2DPiece.FRIEND));
		this.hoard.addPiece(piece);
		for(int i = 0; i < 2; i++)
		{
			this.pieces.add(piece = GameBoard2DPieceFactory.createColonelPiece(null, color, GameBoard2DPiece.FRIEND));
			this.hoard.addPiece(piece);
		}
		for(int i = 0; i < 3; i++)
		{
			this.pieces.add(piece = GameBoard2DPieceFactory.createMajorPiece(null, color, GameBoard2DPiece.FRIEND));
			this.hoard.addPiece(piece);
		}
		for(int i = 0; i < 4; i++)
		{
			this.pieces.add(piece = GameBoard2DPieceFactory.createCaptainPiece(null, color, GameBoard2DPiece.FRIEND));
			this.hoard.addPiece(piece);
		}
		for(int i = 0; i < 4; i++)
		{
			this.pieces.add(piece = GameBoard2DPieceFactory.createLieutenantPiece(null, color, GameBoard2DPiece.FRIEND));
			this.hoard.addPiece(piece);
		}
		for(int i = 0; i < 4; i++)
		{
			this.pieces.add(piece = GameBoard2DPieceFactory.createSergeantPiece(null, color, GameBoard2DPiece.FRIEND));
			this.hoard.addPiece(piece);
		}
		for(int i = 0; i < 5; i++)
		{
			this.pieces.add(piece = GameBoard2DPieceFactory.createMinerPiece(null, color, GameBoard2DPiece.FRIEND));
			this.hoard.addPiece(piece);
		}
		for(int i = 0; i < 8; i++)
		{
			this.pieces.add(piece = GameBoard2DPieceFactory.createScoutPiece(null, color, GameBoard2DPiece.FRIEND));
			this.hoard.addPiece(piece);
		}
		for(int i = 0; i < 6; i++)
		{
			this.pieces.add(piece = GameBoard2DPieceFactory.createBombPiece("images/bomb.png", color, GameBoard2DPiece.FRIEND));
			this.hoard.addPiece(piece);
		}
	}

	/**
	 * Mark all the pieces according to the specified selectability.
	 * @param selectable	boolean
	 */
	public void markAllPieceSelectable(boolean selectable)
	{
		for(GameBoard2DPiece piece : this.pieces)
		{
			piece.setPieceSelectable(selectable);
		}
	}

	/**
	 * Move a piece from one space to another locally and then update the
	 * the opponent.
	 */
	public void movePieceFromSpaceToSpace(GameBoardSpace source, GameBoardSpace target)
	{
		GameBoard2DSpace src = (GameBoard2DSpace)source;
		GameBoard2DSpace tar = (GameBoard2DSpace)target;
		if(src != null && tar != null)
		{

			if(target.addPieceToSpace(src.getPiece())) //Locally add a piece to the space.
			{
				this.removePieceFromSpace(src);	//Remove the piece from the source.
				if(this.client != null)	//Update the opponent
				{
					this.client.sendMovePieceFromSpaceToSpace(this.translateSpaceId(src.getId()), this.translateSpaceId(tar.getId()));
				}
			}
		}

	}

	/**
	 * Complete a request from opponent to move two pieces.
	 * @param sourceSpaceId	Integer 
	 * @param targetSpaceId	Integer
	 */
	public void movePieceFromSpaceToSpace(Integer sourceSpaceId, Integer targetSpaceId)
	{
		GameBoard2DSpace src = this.board.getSpace(sourceSpaceId);
		GameBoard2DSpace tar = this.board.getSpace(targetSpaceId);
		if(src != null && tar != null)
		{
			/*
			 * The target should be empty because all decision making
			 * will remove pieces before requesting to move pieces.
			 */
			if(tar.isEmpty())
			{
				//Unlock the space
				tar.setSpaceSetable(true);
				if(src.getPiece() != null) //Make sure the space still has the piece to move
				{
					if(tar.addPieceToSpace(src.getPiece()))	//Make sure the add was successful
					{
						src.removePieceFromSpace();	//Remove the piece from the source
					}
				}
				//Lock the space.
				tar.setSpaceSetable(false);
			}
		}
	}

	/**
	 * Take action because a piece or space was clicked.
	 * @param e	MouseEvent
	 */
	public void notify(MouseEvent e)
	{
		if(e.getSource() instanceof GameBoard2DSpace) //The player has clicked a seletable space
		{
			GameBoard2DSpace space = (GameBoard2DSpace) e.getSource();
			if(this.getStatus() == GameBoard2DLogic.PLAYER_ACTIVE_TURN && this.board.pieceSelected())
				//The player is taking a turn and has chosen this space to move a piece to.
			{
				this.board.getCurrentlySelectedPiece().getSpace().clearHighlight();
				if(space.getPiece() != null) //If a piece was attacked
					this.determineSpaceWinner(this.board.getCurrentlySelectedPiece().getSpace(), space);
				else
				{
					this.movePieceFromSpaceToSpace(this.board.getCurrentlySelectedPiece().getSpace(), space);
				}
				this.board.clearCurrentlySelectedPiece();
				if(this.getStatus() != GameBoard2DLogic.PLAYER_GAME_ENDED)
				{
					this.endTurn();
				}
			}
		}
		else if(e.getSource() instanceof GameBoard2DPiece)
			//The player has clicked on a selectable piece.
		{
			//If it is the players turn, they are trying to select a piece to move.
			if(this.getStatus() == GameBoard2DLogic.PLAYER_ACTIVE_TURN)
			{
				GameBoard2DPiece clickedpiece = (GameBoard2DPiece) e.getSource();
				GameBoard2DPiece currentSelectedPiece = this.board.getCurrentlySelectedPiece();
				if(currentSelectedPiece == null)
				{
					this.board.setCurrentlySelectedPiece(clickedpiece);
				}
				else if(currentSelectedPiece == clickedpiece)	//Selected the same piece, just clear it.
				{
					this.board.clearCurrentlySelectedPiece();
				}
				else if(currentSelectedPiece.isFoe(clickedpiece))
				{
					this.board.getCurrentlySelectedPiece().getSpace().clearHighlight();
					this.determineSpaceWinner(currentSelectedPiece.getSpace(), clickedpiece.getSpace());
					this.board.clearCurrentlySelectedPiece();
					if(this.getStatus() != GameBoard2DLogic.PLAYER_GAME_ENDED)
					{
						this.endTurn();
					}
				}
			}
		}
	}

	/**
	 * The opponent wins the game.
	 */
	public void opponentWins()
	{
		//End game
		this.gameOver();
		//Display local message
		this.displayResultMessage("You are the loser. Try harder next time.");
		//Send message to the client.
		if(client != null)
		{
			this.client.sendResultMessage("You are victorious!");
		}
	}

	/**
	 * The player is done setting up their board.
	 */
	public void pieceSetupFinished()
	{
		//Set the player to waiting.
		this.setStatus(GameBoard2DLogic.PLAYER_WAITING);
		//Lock the hoard so pieces can't be moved back to it.
		this.hoard.setAllSpacesSetablility(false);
		//Clear any remaining pieces in the hoard.
		this.clearHoard();
		//Lock all board pieces because game hasn't started
		this.board.setAllSpacesSetablility(false);
		//Clear piece DND capability because we don't use it during normal game play
		this.clearDNDCapability();
		if(this.client != null)
		{
			//Send piece data to the opponent
			this.sendOpponentSetupData();
			//Let the client know local is waiting to start.
			this.client.sendWaitingToBegin();

		}
	}

	/**
	 * Set it two players are connected to the server.
	 * @param connected	boolean
	 */
	public void playersConnected(boolean connected)
	{
		this.playersConnected = connected;
	}

	/**
	 * Local player wins.
	 */
	public void playerWins()
	{
		//End the game
		this.gameOver();
		this.displayResultMessage("You are victorious!");
		if(client != null)
		{
			this.client.sendResultMessage("You are the loser. Try harder next time.");
		}
	}

	/**
	 * TODO: Not part of this game, required by protocol
	 */
	public void removePieceFromSpace(GameBoardSpace space)
	{
		space.removePieceFromSpace();
	}

	/**
	 * Remove a piece from a space given the space id.
	 * @param spaceId
	 */
	public void removePieceFromSpace(Integer spaceId)
	{
		GameBoard2DSpace space = this.board.getSpace(spaceId);
		if(space != null)
			space.removePieceFromSpace();

	}

	/**
	 * Restart the game.
	 */
	public void restartGame()
	{
		this.client.sendReadyToStartNewGame();
	}

	/**
	 * Send the location and value of local pieces to the opponent.
	 */
	public void sendOpponentSetupData()
	{
		for (GameBoard2DPiece piece : this.board.getFriendlyPieces())
		{
			if(this.client != null)
			{
				this.client.sendPieceToAdd(piece.getValue(), this.translateSpaceId(piece.getSpace().getId()));
			}
		}
	}

	/**
	 * Set the board used for logic.
	 */
	public void setBoard(GameBoard board)
	{
		this.board = (GameBoard2D) board;
	}

	/**
	 * Set the client protocol for sending messages to server.
	 * @param client	ClientProtocol
	 */
	public void setClientProtocol(ClientProtocol client)
	{
		this.client = client;
	}

	/**
	 * Set the TX handler for all pieces to give them DND capabilities
	 */
	private void setDNDCapability()
	{
		for(GameBoard2DPiece piece : this.pieces)
		{
			piece.setTransferHandler(new GameBoard2DPieceTXHandler());
		}
	}

	/**
	 * Set the hoard to use for this logic.
	 */
	public void setHoard(GameBoardPieceHoard hoard)
	{
		this.hoard = (GameBoard2DPieceHoard) hoard;
	}

	/**
	 * Set the game play status.
	 * @param gameStatus	Integer
	 */
	public void setStatus(Integer gameStatus)
	{
		this.gameStatus = gameStatus;
	}

	/**
	 * Start a new game locally resetting everything.
	 */
	public void startNewGame()
	{
		this.setStatus(GameBoard2DLogic.PLAYER_PIECE_POSITIONING);
		this.board.clearBoard();
		try
		{
			//Set the pieces to play with.
			this.initializePieceHoard();
			//Lock all the pieces.
			this.markAllPieceSelectable(false);
			//Clear DND capability for all pieces
			this.clearDNDCapability();
			//Lock the first 60 spaces so piece placement can commence.
			this.startPiecePlacement(60);
		}
		catch(IOException e)
		{
			new Message("Unable to create pieces.", "Hoard Trouble", Message.ERROR);
			System.err.println("Unable to create pieces.");
			System.exit(-20);
		}
	}

	/**
	 * Lock a specified number of spaces and start the local 
	 * user in setting up their side of the board.
	 */
	public void startPiecePlacement(int lockSpaces)
	{
		this.setStatus(GameBoard2DLogic.PLAYER_PIECE_POSITIONING);
		//Allow pieces to be DNDable.
		this.setDNDCapability();
		//Unlock friendly pieces.
		this.markAllPieceSelectable(true);
		//Lock specified spaces.
		for(int i = 0; i < lockSpaces; i++)
		{
			this.board.setSpaceSetable(i, false);
		}
	}

	/**
	 * Activate turn.
	 */
	public void startTurn()
	{
		this.setStatus(GameBoard2DLogic.PLAYER_ACTIVE_TURN);
		//lock all spaces.
		this.board.setAllSpacesSetablility(false);
		//Allow selecting of friendly pieces
		this.board.markFriendlyPiecesSelectable();
	}

	/**
	 * Translate a local space id to a opponent space id.
	 * @param actualId	Integer local id
	 * @return	Integer translated id
	 */
	public Integer translateSpaceId(Integer actualId)
	{
		/*
		 * The translated id is just the total number of spaces
		 * minus the current space id.
		 */
		return (this.board.getRows() * this.board.getColumns()) - 1 - actualId;
	}
}


